<template>
  <el-upload
    drag
    ref="upload"
    action=""
    list-type="picture"
    :file-list="fileListData"
    :accept="accept"
    :show-file-list="false"
    :multiple="multiple"
    :before-upload="beforeUpload"
    :on-exceed="oneExceed"
    :http-request="customUpload"
    :on-success="handleSuccess"
    :on-error="onError"
    style="width: 100%"
    :limit="maxLength"
    v-loading="loading"
    element-loading-text="上传中"
  >
    <div class="upload-picture-card">
      <div style="display: flex; align-items: center; justify-content: center">
        <img style="width: 20px; height: 20px; margin-right: 10px" src="@/assets/images/pdf.png" fit="cover" />
        <div class="upload-name">{{ uploadName }}</div>
      </div>
      <div class="upload__tip">{{ tips }}</div>
    </div>
    <template #tip>
      <div class="el-upload__tip" style="text-align: left; color: #4e5969">
        本次上传{{ successNum + errorNum }}个文件，{{ errorNum }}个文件上传失败
      </div>
      <div class="upload-file-li">
        <div v-for="(item, index) in fileListData" :key="item" class="upload-file-item">
          <el-image style="width: 24px; height: 24px" :src="item.fileUrl" :fit="fit" :preview-src-list="[item.fileUrl]">
            <template #error>
              <div class="image-slot">
                <img style="width: 24px; height: 24px" src="@/assets/images/errpdf.png" alt="" />
              </div>
            </template>
          </el-image>
          <div class="flile-name">{{ item.name || item.fileName }}</div>
          <img class="del-img" src="@/assets/images/del.png" alt="" @click="handleRemove(index)" />
          <el-progress
            v-if="multipartOssStore.loadingArr[item.fileId] !== 100"
            style="width: 100%"
            :percentage="multipartOssStore.loadingArr[item.fileId]"
            :indeterminate="true"
          />
        </div>
      </div>
    </template>
  </el-upload>
</template>

<script setup>
/**
 * TODO:PDf上传组件，后续优化可以和AliOssUpload组件合并,封装完整的附件、图片、视频上传预览组件
 */
import { computed, getCurrentInstance, ref, watch } from "vue";
import { dayjs } from "element-plus";
import { fileReadRole, setACL, signatureUrl } from "@/utils/aliOssUpload";
import useMultipartOssStore from "@/store/modules/multipartOss";
import defaultConfig from "@/settings";
import { getVideoTime } from "./utils";

const props = defineProps({
  tips: {
    type: String,
    default: "支持上传pdf/jpg/png/jpeg等常见规格，单个文件不超过20M，最多上传50个"
  },
  fileList: {
    type: Array,
    default: () => []
  },
  fileType: {
    type: String,
    default: "image"
  },
  itemSize: {
    type: String,
    default: "84px"
  },
  accept: {
    type: String,
    default: ".jpg"
  },
  maxSize: {
    type: Number,
    default: 20
  },
  maxLength: {
    type: Number,
    default: 50
  },
  tip: {
    type: String,
    default: ""
  },
  uploadName: {
    type: String,
    default: "上传合同"
  },
  disabled: Boolean,
  multiple: Boolean,
  isLimitDuration: Boolean,
  limitDuration: {
    type: Number,
    default: 60
  }
});
const emits = defineEmits(["uploadSuccess", "update:modelValue", "uploadRemove", "uploadErr"]);
const { proxy } = getCurrentInstance();
const multipartOssStore = useMultipartOssStore();

const fileListData = ref([]);
const successNum = ref(0);
const errorNum = ref(0);
const loading = ref(false);
watch(
  () => props.fileList,
  newVal => {
    props.fileList.forEach(item => {
      item.fileUrl && (multipartOssStore.loadingArr[item.fileId] = 100);
    });
    fileListData.value = [...newVal];
  },
  { immediate: true, deep: true }
);

/**
 * TODO:限制文件类型，还可以在优化，目前文件类型必须传入组件
 */
const acceptTip = computed(() => {
  return props.accept?.replace(/\./g, "")?.replace(/,/g, "/") || "";
});
const beforeUpload = async file => {
  const suffix = file.name?.slice(file.name.lastIndexOf(".")) || "";
  const fileTypes = props.accept?.split(",") || [];
  const maxSize = file.size / 1024 / 1024 < 20;
  const isInFileType = fileTypes.includes(suffix);
  if (!isInFileType) {
    proxy.$modal.msgError(`只能上传${acceptTip.value}类型的文件!`);
    return false;
  }
  if (!maxSize) {
    proxy.$modal.msgError(`单个文件大小不能超过${props.maxSize}M!`);
    errorNum.value++;
    return false;
  }
  if (props.isLimitDuration) {
    const duration = await getVideoTime(file);
    if (duration > props.limitDuration) {
      proxy.$modal.msgError(`单个文件大小不能超过${props.limitDuration}秒!`);
      return false;
    }
  }
  return true;
};
const oneExceed = () => {
  proxy.$modal.msgError(`最多上传${props.maxLength}个文件`);
  return false;
};
const getSuffix = fileName => {
  return fileName.slice(fileName.lastIndexOf(".") + 1);
};
const getFileName = fileName => {
  return fileName.slice(0, fileName.lastIndexOf("."));
};
const fileToBlob = file => {
  return {
    fileId: file.uid,
    uid: file.uid,
    name: file.name,
    size: file.size,
    type: file.type,
    suffix: file.suffix,
    fileUrl: URL.createObjectURL(file)
  };
};
const customUpload = async option => {
  console.log(option, 888888);
  loading.value = true;
  multipartOssStore.loadingArr[option.file.uid] = 0;
  const nowTime = dayjs().format("mm-ss");
  let file = option.file,
    fileName = option.file.name;
  // fileName = `${getFileName(fileName)}-${nowTime}.${getSuffix(fileName)}`;
  fileName = file.uid + `-${nowTime}.${getSuffix(fileName)}`;
  file = new File([file], encodeURI(fileName), { type: file.type });
  let objName = `${defaultConfig.fileFolder}/${file.name}`;
  // fileListData.value.push(fileToBlob(option.file));
  multipartOssStore
    .submit(objName, file, option.file.uid)
    .then(async res => {
      await setACL(objName, fileReadRole.publicRead);
      const fileUrl = await signatureUrl(objName);
      emits("uploadSuccess", {
        fileId: option.file.uid,
        fileUrl: fileUrl ? `${fileUrl}`.split("?")[0] : "",
        name: option.file.name,
        fileName: option.file.name
      });
      successNum.value++;
      loading.value = false;
    })
    .catch(err => {
      console.log(err);
      // fileListData.value.pop();
      errorNum.value++;
      emits("uploadErr", err);
      loading.value = false;
    });
};
// 上传成功
const handleSuccess = () => {};
// 上传失败
const onError = () => {
  successNum.value--;
};
// 删除
const handleRemove = index => {
  console.log(index);
  successNum.value--;
  emits("uploadRemove", index);
  if (index === 0) {
    successNum.value = 0;
    errorNum.value = 0;
  }
};
</script>

<style lang="scss" scoped>
$picture-card-size: 84px;
.design {
  i {
    padding: 10px;
    font-size: xx-large;
    background: white;
    border: 1px dashed #8c8c8c;
  }
}

:deep(.el-upload--text) {
  width: 100% !important;
  height: 100% !important;
}

:deep(.el-progress-circle) {
  width: 84px !important;
  height: 84px !important;
}

.preview-dialog {
  :deep(.el-dialog) {
    video {
      width: 100%;
      height: 50vh !important;
    }
  }
}

.upload__tip {
  font-size: 12px;
  color: #86909c;
  margin-top: 10px;
}

:deep(.el-upload-dragger) {
  background: #eaecf0 !important;
  padding: 10px !important;
}

.upload-name {
  font-size: 14px;
  color: #007dff;
}

.upload-file-li {
  display: flex;
  flex-flow: wrap;
  overflow: auto;
  max-height: 300px;
}

.upload-file-item {
  position: relative;
  display: flex;
  flex-flow: wrap;
  border-radius: 4px 4px 4px 4px;
  border: 1px solid #eaecf0;
  padding: 8px 10px;
  margin: 15px 10px 0;
}

.flile-name {
  width: 65px;
  margin-left: 10px;
  overflow: hidden; /*内容超出后隐藏*/
  text-overflow: ellipsis; /*超出内容显示为省略号*/
  white-space: nowrap; /*文本不进行换行*/
}

.del-img {
  width: 14px;
  height: 14px;
  position: absolute;
  top: -7px;
  right: -7px;
  cursor: pointer;
}
</style>
